# encoding: utf-8
""" 
@version: v1.0 
@author: autumner 
@license: Apache Licence  
@contact: 18322313385@163.com 
@site:  https://gitee.com/autumner/pythoncookbook
@software: PyCharm 
@file: net_xmlrpc_upload_cmd.py 
@time: 2019/7/25 下午3:13
@note:
基于xmlrpc的文件上传下载文件显示查询-cmd端
"""
from xmlrpc.client import ServerProxy, SafeTransport
from xmlrpc.client import Binary
from cmd import Cmd
import os
import sys
import ssl

# 证书类
class SslClient(SafeTransport):
    def __init__(self, cafile, certfile=None, keyfile=None):
        SafeTransport.__init__(self)
        self._cafile = cafile
        self._certfile = certfile
        self._keyfile = keyfile

    def get_ssl_context(self):

        context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
        context.load_verify_locations(self._cafile)
        if self._certfile:
            context.load_cert_chain(certfile=self._certfile, keyfile=self._keyfile)
        context.verify_mode = ssl.CERT_REQUIRED

        return context


# 初始化证书
KEYFILE='client_key.pem'
CERTFILE='client_cert.pem'
CA_CERTS='server_cert.pem'

# 实例化证书
ssl_con=SslClient(keyfile=KEYFILE, certfile=CERTFILE, cafile=CA_CERTS)

class Client(Cmd):
    '基于文本界面上传下载操作'
    prompt = '>'

    def __init__(self, url, directory):
        '初始化操作'
        Cmd.__init__(self)
        self._ldir = directory
        self._serv = ServerProxy(url, context=ssl_con.get_ssl_context(), allow_none=True)

    def do_list(self, arg):
        '显示服务端所有文件'
        for li in self._serv.show(): print(f"{li[0]} {li[1]} {li[2]}")

    def do_find(self, arg):
        '模糊查找指定文件'
        for li in self._serv.query(arg): print(f"{li[0]} {li[1]} {li[2]}")

    def do_fetch(self, arg):
        '下载文件'
        if self._serv.down(arg):
            with open(os.path.join(self._ldir, arg), 'wb') as f:
                f.write(self._serv.down(arg).data)
            print(f"{arg},下载完成")
        else:
            print(f"{arg} no found!")

    def do_push(self, arg):
        '上传文件'
        fpath, filename = os.path.split(arg)
        '判断系统平台路径'
        if ("\\" in fpath):
            newpath = arg.replace("\\", "/")
        else:
            newpath = arg

        try:
            print(newpath)
            with open(arg, 'rb') as f:
                result = Binary(f.read())
                if self._serv.upload(result, newpath): print(f'{filename},上传完成!')
        except:
            print(f"{arg}上传文件路径有误！")

    def do_exit(self, arg):
        '退出cmd'
        print("Bye!")
        sys.exit()
    do_EOF = do_exit # EOF与‘exit’等价


if __name__ == '__main__':

    # ldir = '/home/autumner'
    # client = Client('http://localhost:18000', ldir)
    # client.cmdloop()

    if len(sys.argv) != 3:
        print(f"Usage:{sys.argv[0]} https://localhost:port download_dir", file=sys.stderr)
        raise SystemExit(1)
    client = Client(sys.argv[1], sys.argv[2])
    print('欢迎使用基于文本界面的文件上传下载工具，请输入help进行帮助查看')
    client.cmdloop()

"""
Example usage
Terminal:
python client.py https://localhost:port download_dir
https://localhost:port:服务端地址和端口
download_dir：下载文件的本地目录
help:
list:查看服务端所有文件
find arg:查找服务端文件
fetch arg:下载文件
push arg:上传本地文件，arg:是绝对路径加文件名
EOF || exit:退出文本界面
证书有效期2020.7
"""

